package com.ctshk.rpc.season.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SeasonType;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.season.dto.CabinClassDTO;
import com.ctshk.rpc.season.dto.PackageProductCostDTO;
import com.ctshk.rpc.season.dto.SeasonFixedProductPackageShipDTO;
import com.ctshk.rpc.season.entity.SeasonFixedProductPackageShip;
import com.ctshk.rpc.season.mapper.SeasonFixedProductPackageShipMapper;
import com.ctshk.rpc.season.req.PassengerReq;
import com.ctshk.rpc.season.req.SeasonFixedProductPackageShipReq;
import com.ctshk.rpc.season.req.UpdatePackageProductReq;
import com.ctshk.rpc.season.service.ISeasonFixedProductPackageShipService;
import com.ctshk.rpc.ship.dto.ShipPriceRemainderDTO;
import com.ctshk.rpc.ship.service.IShipProductService;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 套票-固定套票单项产品打包-船表 服务实现类
 * </p>
 *
 * @author 杨林
 * @since 2021-03-09
 */
@DubboService
public class SeasonFixedProductPackageShipServiceImpl extends ServiceImpl<SeasonFixedProductPackageShipMapper, SeasonFixedProductPackageShip> implements ISeasonFixedProductPackageShipService {

    @Autowired
    private SeasonFixedProductPackageShipMapper seasonFixedProductPackageShipMapper;
    //船票服务
    @DubboReference
    private IShipProductService shipProductService;

    /* @MethodName: 获取船票的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/26 19:15
     **/
    @Override
    public PackageProductCostDTO getShipProductPrice(Long productId, LocalDate departureDate, Long userId, Integer channelType) {
        PackageProductCostDTO costDTO = new PackageProductCostDTO();
        try {
            ShipPriceRemainderDTO result = shipProductService.findShipSalePriceInfoHandle(channelType, productId, departureDate, userId);
            if (null != result && result.getSolidNumber() > 0) {
                costDTO.setCostPrice(result.getPrice());
                costDTO.setStock(result.getSolidNumber());
            }
        } catch (Exception e) {
            log.error("调用船票服务获取价格发生异常", e);
        }
        return costDTO;
    }

    /* @MethodName: 固定套票默认船票的价格
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/19 13:32
     **/
    public BigDecimal getDefaultShipPrice(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        BigDecimal bd = BigDecimal.ZERO;
        //获取默认的 船票产品 有返还 有两条
        List<SeasonFixedProductPackageShip> resultList = seasonFixedProductPackageShipMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageShip>().lambda().
                        eq(SeasonFixedProductPackageShip::getIsDefault, SeasonType.YES_DEFAULT.getCode()).
                        eq(SeasonFixedProductPackageShip::getIsDeleted, IsDeletedCode.NO.getCode()).
                        eq(SeasonFixedProductPackageShip::getPackageId, packageId)
        );
        boolean departFlag = true;
        boolean returnFlag = true;
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageShip result : resultList) {
                if (departFlag && SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(result.getTripType())) {
                    bd.add(getShipProductPrice(result.getProductId(), departDate, userId, channelType).getCostPrice());
                    departFlag = false;
                }
                if (returnFlag && SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(result.getTripType())) {
                    bd.add(getShipProductPrice(result.getProductId(), arrDate, userId, channelType).getCostPrice());
                    returnFlag = false;
                }
            }
        }
        return bd;
    }

    @Override
    public List<SeasonFixedProductPackageShipDTO> getShipByPackageId(Long packageId, LocalDate departDate, LocalDate arrDate, Long userId, Integer channelType) {
        Multimap<String, SeasonFixedProductPackageShipDTO> map = LinkedHashMultimap.<String, SeasonFixedProductPackageShipDTO>create();
        List<SeasonFixedProductPackageShip> resultList = seasonFixedProductPackageShipMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageShip>().lambda().
                        eq(SeasonFixedProductPackageShip::getPackageId, packageId)
        );
        List<SeasonFixedProductPackageShipDTO> resultDtoList = new ArrayList<>();
        if (null != resultList && resultList.size() > 0) {
            for (SeasonFixedProductPackageShip result : resultList) {
                SeasonFixedProductPackageShipDTO resultDto = EntityUtil.copy(result, SeasonFixedProductPackageShipDTO.class);
                if (SeasonType.JOURNEY_TYPE_DEPART.getKey().equals(result.getTripType())) {
                    resultDto.setCost(getShipProductPrice(result.getProductId(), departDate, userId, channelType).getCostPrice());
                }
                if (SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(result.getTripType())) {
                    resultDto.setCost(getShipProductPrice(result.getProductId(), arrDate, userId, channelType).getCostPrice());
                }
                map.put(result.getVoyage(), resultDto);
            }
        }
        for (String key : map.keySet()) {
            SeasonFixedProductPackageShipDTO flightDto = null;
            List<CabinClassDTO> CabinClassDTOs = new ArrayList<>();
            Collection<SeasonFixedProductPackageShipDTO> CabinClassVos = map.get(key);
            //遍历Multimap，得到每个航班下面的坐席的具体值:比如 一等，二等
            for (SeasonFixedProductPackageShipDTO value : CabinClassVos) {
                if (null == flightDto) {
                    flightDto = EntityUtil.copy(value, SeasonFixedProductPackageShipDTO.class);
                }
                CabinClassDTOs.add(EntityUtil.copy(value, CabinClassDTO.class));
            }
            CabinClassDTOs.sort(new Comparator<CabinClassDTO>() {
                @Override
                public int compare(CabinClassDTO o1, CabinClassDTO o2) {
                    return o2.getCost().compareTo(o1.getCost());
                }
            });
            flightDto.setCabinClassDTOs(CabinClassDTOs);
            resultDtoList.add(flightDto);
        }
        return resultDtoList;
    }

    /* @MethodName: 批量保存 船票产品信息
     * @Description: TODO
     * @Param: userId 用户id  productId 产品id packageId 打包id  shipReqList 船票集合
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/9 18:27
     **/
    @Override
    public void batchShipProduct(Long userId, Long packageId, List<SeasonFixedProductPackageShipReq> shipReqList) {
        LocalDateTime now = LocalDateTime.now();
        List<SeasonFixedProductPackageShip> shipList = shipReqList.stream().map(
                shipReq -> {
                    SeasonFixedProductPackageShip ship = EntityUtil.copy(shipReq, SeasonFixedProductPackageShip.class);
                    ship.setCreateId(userId);
                    ship.setPackageId(packageId);
                    ship.setGmtCreate(now);
                    ship.setIsDeleted(IsDeletedCode.NO.getCode());
                    return ship;
                }
        ).collect(Collectors.toList());

        seasonFixedProductPackageShipMapper.insertBatchSomeColumn(shipList);
    }


    /* @MethodName: 获取固定套票 船票产品 信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 13:52
     **/
    @Override
    public List<SeasonFixedProductPackageShipDTO> getSeasonFixedProductShipDtoList(Long packageId) {
        List<SeasonFixedProductPackageShip> productPackageShipList = getSeasonFixedProductShipList(packageId);
        List<SeasonFixedProductPackageShipDTO> list = new LinkedList<>();
        if (null != productPackageShipList && productPackageShipList.size() > 0) {
            list = productPackageShipList.stream().map(
                    Ship -> {
                        SeasonFixedProductPackageShipDTO shipDto = EntityUtil.copy(Ship, SeasonFixedProductPackageShipDTO.class);
                        return shipDto;
                    }
            ).collect(Collectors.toList());
        }
        return list;
    }

    /* @MethodName: 删除原来的船票产品
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/12 16:26
     **/
    @Override
    public void deletePreviousShip(Long userId, Long packageId) {
        LocalDateTime now = LocalDateTime.now();
        UpdateWrapper<SeasonFixedProductPackageShip> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("modified_id", userId);//修改人
        updateWrapper.set("is_deleted", IsDeletedCode.YES.getCode());//删除
        updateWrapper.set("gmt_modified", now);//修改时间
        updateWrapper.eq("package_id", packageId);
        seasonFixedProductPackageShipMapper.update(null, updateWrapper);
    }


    /* @MethodName: 获取船票信息差价信息
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/22 18:01
     **/
    @Override
    public List<SeasonFixedProductPackageShipDTO> getShipDifferencePrice(UpdatePackageProductReq req) {
        Long packageId = req.getPackageId();
        String journeyType = req.getJourneyType();//行程类型
        //查询日期 当是返程的时候 用结束日期
        LocalDate queryDate = req.getStartDate();
        if (SeasonType.JOURNEY_TYPE_RETURN.getKey().equals(journeyType)) {
            queryDate = req.getEndDate();
        }
        List<SeasonFixedProductPackageShipDTO> list = new LinkedList<>();
        SeasonFixedProductPackageShipDTO shipDTO = getSeasonFixedDefaultProductShip(packageId, journeyType, queryDate, req.getPassengerReqList(), req.getUserId());
        list.add(shipDTO);
        BigDecimal flagCost = shipDTO.getCost();
        List<SeasonFixedProductPackageShip> shipList = getSeasonFixedProductShipList(packageId, journeyType);
        LocalDate finalQueryDate = queryDate;
        shipList.stream().forEach(
                ship -> {

                    SeasonFixedProductPackageShipDTO shipDto = EntityUtil.copy(ship, SeasonFixedProductPackageShipDTO.class);
                    BigDecimal shopCost = getShipProductPrice(ship.getProductId(), finalQueryDate, req.getUserId(), 1).getCostPrice();
                    shipDto.setCost(shopCost);
                    if (shopCost.compareTo(BigDecimal.ZERO) == 0) {//表示没有库存
                        shipDto.setPriceDifference("售罄");
                    } else {
                        shipDto.setPriceDifference(String.valueOf(flagCost.subtract(shopCost)));//减法
                    }
                    list.add(shipDto);
                });


        return list;

    }


    /* @MethodName: 获取固定套票 船票信息 根据条件
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/22 18:04
     **/
    private List<SeasonFixedProductPackageShip> getSeasonFixedProductShipList(Long packageId, String tripType) {
        List<SeasonFixedProductPackageShip> list = seasonFixedProductPackageShipMapper.selectList(
                new QueryWrapper<SeasonFixedProductPackageShip>().lambda()
                        .eq(SeasonFixedProductPackageShip::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageShip::getTripType, tripType)
                        .eq(SeasonFixedProductPackageShip::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageShip::getIsDefault, SeasonType.NO_DEFAULT.getCode())
        );
        return list;

    }

    /* @MethodName: 获取固定套票 船票 默认船票的 根据条件
     * @Description: TODO
     * @Param:
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/22 18:04
     **/
    private SeasonFixedProductPackageShipDTO getSeasonFixedDefaultProductShip(Long packageId, String tripType, LocalDate queryDate, List<PassengerReq> passengerReqList, Long userId) {
        SeasonFixedProductPackageShip ship = seasonFixedProductPackageShipMapper.selectOne(
                new QueryWrapper<SeasonFixedProductPackageShip>().lambda()
                        .eq(SeasonFixedProductPackageShip::getPackageId, packageId)
                        .eq(SeasonFixedProductPackageShip::getTripType, tripType)
                        .eq(SeasonFixedProductPackageShip::getIsDeleted, IsDeletedCode.NO.getCode())
                        .eq(SeasonFixedProductPackageShip::getIsDefault, SeasonType.YES_DEFAULT.getCode())
        );
        SeasonFixedProductPackageShipDTO shipDTO = EntityUtil.copy(ship, SeasonFixedProductPackageShipDTO.class);
        BigDecimal shopCost = getShipProductPrice(shipDTO.getProductId(), queryDate, userId, 1).getCostPrice();
        shipDTO.setCost(shopCost);
        if (shopCost.compareTo(BigDecimal.ZERO) == 0) {
            shipDTO.setPriceDifference("售罄");
        } else {
            shipDTO.setPriceDifference("0");
        }
        return shipDTO;
    }


    /* @MethodName: 获取固定套票 船票产品 信息
     * @Description: TODO
     * @Param: fixedSeasonId 固定套票id   packageId 产品打包id
     * @Return:
     * @Author: 杨林
     * @Date:2021/3/11 13:52
     **/
    private List<SeasonFixedProductPackageShip> getSeasonFixedProductShipList(Long packageId) {
        QueryWrapper<SeasonFixedProductPackageShip> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("package_id", packageId);
        queryWrapper.eq("is_deleted", IsDeletedCode.NO.getCode());
        return seasonFixedProductPackageShipMapper.selectList(queryWrapper);
    }
}
